package com.travel.server.manager.impl.dal;

import com.travel.common.CommonConstant;
import com.travel.common.exception.WorkCode;
import com.travel.common.exception.WorkException;
import com.travel.common.util.CollectionUtil;
import com.travel.server.manager.dao.OrderInfoDao;
import com.travel.server.manager.model.OrderInfo;
import com.travel.server.manager.model.OrderInfoExample;
import com.travel.server.manager.model.dto.CustomerOrderDto;
import com.travel.server.manager.model.dto.OrderExcelDto;
import com.travel.server.manager.model.dto.OrderItemDto;
import com.travel.server.manager.model.dto.OrderRefundItemDto;
import com.travel.server.manager.model.dto.data.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * @Author: LiZhenhui
 * @Date: 2018/11/5 18:26
 * @Desc:
 */
@Component
@Slf4j
public class OrderDal {

    @Autowired
    private OrderInfoDao orderInfoDao;

    public PageDto<OrderItemDto> select(OrderInfoParam param){
        OrderInfoExample example = makeExample(param);
        int total = orderInfoDao.countByExample(example);
        example.setOrderByClause("create_time desc");
        List<OrderItemDto> list = orderInfoDao.selectByPage(example);

        PageDto<OrderItemDto> pageDto = new PageDto<>();
        pageDto.setTotal(total);
        pageDto.setList(list);

        return pageDto;
    }

    public List<OrderExcelDto> selectExcelData(OrderInfoParam param){
        OrderInfoExample example = makeExample(param);
        example.setOrderByClause("create_time desc");
        return orderInfoDao.selectExcelData(example);
    }

    public PageDto<OrderRefundItemDto> selectRefund(OrderInfoParam param){
        OrderInfoExample example = makeExample(param);
        int total = orderInfoDao.selectRefundPage(example);
        example.setOrderByClause("create_time desc");
        List<OrderRefundItemDto> list = orderInfoDao.selectRefundByPage(example);

        PageDto<OrderRefundItemDto> pageDto = new PageDto<>();
        pageDto.setTotal(total);
        pageDto.setList(list);

        return pageDto;
    }

    public int batchInsert(List<OrderInfo> list){
        return orderInfoDao.batchInsert(list);
    }

    public CustomerOrderDto selectCustomerOrder(Integer customerId){
        return orderInfoDao.selectCountByCustomerId(customerId);
    }

    public List<OrderInfo> selectByExample(OrderInfoParam param){
        OrderInfoExample example = makeExample(param);
        return orderInfoDao.selectByExample(example);
    }

    public List<SpecialOrderDto> selectSpecialOrder(Date startTime, Date endTime){
        return orderInfoDao.selectSpecialOrder(startTime, endTime);
    }

    public List<DayApplyDto> selectDayApply(Date startTime, Date endTime){
        return orderInfoDao.selectDayApply(startTime, endTime);
    }

    public List<OrderDataDto> selectOrderData(Date startTime, Date endTime){
        return orderInfoDao.selectOrderData(startTime, endTime);
    }

    public List<AmountSectionDto> selectAmountSection(Date startTime, Date endTime){
        return orderInfoDao.selectAmountSection(startTime, endTime);
    }

    public List<OrderAnalysisDto> selectAnalysis(Date startTime, Date endTime, Integer offset, Integer limit){
        return orderInfoDao.selectAnalysis(startTime, endTime, offset, limit);
    }

    public List<OrderSaleTargetDto> selectSaleTarget(Date startTime, Date endTime, Integer offset, Integer limit){
        return orderInfoDao.selectSaleTarget(startTime, endTime, offset, limit);
    }

    public List<WholeAllDto> selectAllData(Date startTime, Date endTime){
        return orderInfoDao.selectAllData(startTime, endTime);
    }

    public List<WholeDataDto> selectWholeData(){
        return orderInfoDao.selectWholeData();
    }

    public List<WholeTrendDto> selectWholeTrend(Date startTime, Date endTime, Integer time){
        return orderInfoDao.selectWholeTrend(startTime, endTime, time);
    }

    public List<TradeDto> selectTradeList(Date startTime, Date endTime, Integer offset, Integer limit){
        return orderInfoDao.selectTradeList(startTime, endTime, offset, limit);
    }

    public int selectTradeCount(Date startTime, Date endTime){
        return orderInfoDao.selectTradeCount(startTime, endTime);
    }

    public Integer selectSumPayAmount(Date startTime, Date endTime){
        return orderInfoDao.selectSumPayAmount(startTime, endTime);
    }

    public Integer selectCountPayNum(Date startTime, Date endTime){
        return orderInfoDao.selectCountPayNum(startTime, endTime);
    }

    public OrderInfo selectById(Integer id){
        OrderInfo orderInfo = orderInfoDao.selectByPrimaryKey(id);
        if(orderInfo == null){
            log.error("未查询到订单记录, id {}", id);
            throw new WorkException(WorkCode.RECORD_NOT_EXIST);
        }
        return orderInfo;
    }

    public OrderInfo selectByOrderId(String orderId){
        OrderInfoParam param = new OrderInfoParam();
        param.setOrderId(orderId);
        List<OrderInfo> list = selectByExample(param);
        return CollectionUtil.getFirst(list);
    }

    public Integer insertOrUpdate(OrderInfo orderInfo){
        if(orderInfo.getId() == null){
            orderInfoDao.insertSelective(orderInfo);
        }else{
            orderInfoDao.updateByPrimaryKey(orderInfo);
        }
        return orderInfo.getId();
    }

    public List<ProjectApplyDto> selectProjectApply(Date startTime, Date endTime, Integer offset, Integer limit){
        return orderInfoDao.selectProjectApply(startTime, endTime, offset, limit);
    }

    private OrderInfoExample makeExample(OrderInfoParam param){
        OrderInfoExample example = new OrderInfoExample();
        OrderInfoExample.Criteria criteria = example.or();
        if(StringUtils.isNotBlank(param.getOrderId())){
            criteria.andOrderIdEqualTo(param.getOrderId());
        }
        if(StringUtils.isNotBlank(param.getOutOrderId())){
            criteria.andOutOrderIdEqualTo(param.getOutOrderId());
        }
        if(StringUtils.isNotBlank(param.getPayId())){
            criteria.andPayIdEqualTo(param.getPayId());
        }
        if(param.getStartOrderTime() != null){
            criteria.andOrderTimeGreaterThanOrEqualTo(param.getStartOrderTime());
        }
        if(param.getEndOrderTime() != null){
            criteria.andOrderTimeLessThanOrEqualTo(param.getEndOrderTime());
        }
        if(StringUtils.isNotBlank(param.getOrderState())){
            criteria.andOrderStateEqualTo(param.getOrderState());
        }
        if(StringUtils.isNotBlank(param.getPayType())){
            criteria.andPayTypeEqualTo(param.getPayType());
        }
        if(StringUtils.isNotBlank(param.getOrderType())){
            criteria.andOrderTypeEqualTo(param.getOrderType());
        }
        if(param.getIsStars() != null && CommonConstant.YES.equals(param.getIsStars())){
            criteria.andStarsIsNotNull();
        }
        if(!CollectionUtil.isEmpty(param.getStepList())){
            criteria.andOrderStepIn(param.getStepList());
        }
        if(!CollectionUtil.isEmpty(param.getSpecialIdList())){
            criteria.andSpecialIdIn(param.getSpecialIdList());
        }
        if(!CollectionUtil.isEmpty(param.getRefundStateList())){
            criteria.andRefundStateIn(param.getRefundStateList());
        }
        if(!CollectionUtil.isEmpty(param.getOrderChargeIdList())){
            criteria.andOrderChargeIdIn(param.getOrderChargeIdList());
        }
        if(param.isRefund()){
            criteria.andRefundStateIsNotNull();
        }
        if(!CollectionUtil.isEmpty(param.getIdList())){
            criteria.andIdIn(param.getIdList());
        }
        if(!CollectionUtil.isEmpty(param.getCustomerIdList())){
            criteria.andCustomerIdIn(param.getCustomerIdList());
        }
        if(param.getOffset() != null && param.getLimit() != null){
            example.setOffset(param.getOffset());
            example.setLimit(param.getLimit());
        }
        return example;
    }

    @Data
    public static class OrderInfoParam{

        private String orderId;

        private String outOrderId;

        private String payId;

        private List<Integer> orderChargeIdList;

        private List<Integer> customerIdList;

        private Date startOrderTime;

        private Date endOrderTime;

        private String orderState;

        private List<String> stepList;

        private String payType;

        private String orderType;

        private Integer isStars;

        private List<Integer> specialIdList;

        private List<String> refundStateList;

        private List<Integer> idList;

        private Integer offset;

        private Integer limit;

        private boolean refund = false;
    }
}
